package cn.itbat.license.IntelliUtil;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;

/**
 * 数字签名验证
 *
 * @author huahui.wu. (;￢＿￢)
 * Created on 2018/5/8.
 */
public class RSASign {
    /**
     * 签名1
     */
    private static String key1 = "MIIBOgIBAAJBALecq3BwAI4YJZwhJ+snnDFj3lF3DMqNPorV6y5ZKXCiCMqj8OeOmxk4YZW9aaV9"
            + "ckl/zlAOI0mpB3pDT+Xlj2sCAwEAAQJAW6/aVD05qbsZHMvZuS2Aa5FpNNj0BDlf38hOtkhDzz/h"
            + "kYb+EBYLLvldhgsD0OvRNy8yhz7EjaUqLCB0juIN4QIhAOeCQp+NXxfBmfdG/S+XbRUAdv8iHBl+"
            + "F6O2wr5fA2jzAiEAywlDfGIl6acnakPrmJE0IL8qvuO3FtsHBrpkUuOnXakCIQCqdr+XvADI/UTh"
            + "TuQepuErFayJMBSAsNe3NFsw0cUxAQIgGA5n7ZPfdBi3BdM4VeJWb87WrLlkVxPqeDSbcGrCyMkC"
            + "IFSs5JyXvFTreWt7IQjDssrKDRIPmALdNjvfETwlNJyY";

    /**
     * 签名2
     */
    private static String key2 = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAt5yrcHAAjhglnCEn"
            + "6yecMWPeUXcMyo0+itXrLlkpcKIIyqPw546bGThhlb1ppX1ySX/OUA4jSakHekNP"
            + "5eWPawIDAQABAkBbr9pUPTmpuxkcy9m5LYBrkWk02PQEOV/fyE62SEPPP+GRhv4Q"
            + "Fgsu+V2GCwPQ69E3LzKHPsSNpSosIHSO4g3hAiEA54JCn41fF8GZ90b9L5dtFQB2"
            + "/yIcGX4Xo7bCvl8DaPMCIQDLCUN8YiXppydqQ+uYkTQgvyq+47cW2wcGumRS46dd"
            + "qQIhAKp2v5e8AMj9ROFO5B6m4SsVrIkwFICw17c0WzDRxTEBAiAYDmftk990GLcF"
            + "0zhV4lZvztasuWRXE+p4NJtwasLIyQIgVKzknJe8VOt5a3shCMOyysoNEg+YAt02"
            + "O98RPCU0nJg=";

    private static String sign1(String content) {
        return RSASign.sign1(content.getBytes(), key1);
    }

    private static String sign2(String content) {
        return RSASign.sign2(content.getBytes(), key2);
    }

    /**
     * 不同的加密方式
     *
     * @param content 请求参数
     * @return
     */
    public static String sign(String content) {
        return sign2(content);
//        return sign1(content);
    }

    /**
     * 传入秘钥为ASN格式
     * 私钥签名程序，privateKey是私钥base64编码字符串，即私钥文件数据中，中间的主体部分
     *
     * @param content    请求参数
     * @param privateKey 私钥
     * @return
     */
    private static String sign1(byte[] content, String privateKey) {
        try {
            byte[] keybyte = Base64.decode(privateKey);
            ASN1InputStream in = new ASN1InputStream(keybyte);
            ASN1Primitive obj = in.readObject();
            RSAPrivateKeyStructure pStructure = RSAPrivateKeyStructure.getInstance(obj);
            RSAPrivateKeySpec spec = new RSAPrivateKeySpec(pStructure.getModulus(), pStructure.getPrivateExponent());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyFactory.generatePrivate(spec);
            java.security.Signature signature = java.security.Signature.getInstance("MD5WithRSA");
            signature.initSign(priKey);
            signature.update(content);
            byte[] signed = signature.sign();
            return cn.itbat.license.IntelliUtil.Hex.bytesToHexString(signed);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 传入秘钥为ASN格式
     * 私钥签名程序，privateKey是私钥base64编码字符串，即私钥文件数据中，中间的主体部分
     *
     * @param content    请求参数
     * @param privateKey 私钥base64编码字符串
     * @return
     */
    private static String sign2(byte[] content, String privateKey) {
        try {
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
            java.security.Signature signature = java.security.Signature.getInstance("MD5WithRSA");
            signature.initSign(priKey);
            signature.update(content);
            byte[] signed = signature.sign();
            return cn.itbat.license.IntelliUtil.Hex.bytesToHexString(signed);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
